package au.edu.unsw.editingtool.db;

import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Date;
import java.util.Hashtable;
import java.util.LinkedList;

import au.edu.unsw.editingtool.global.EditingToolException;
import au.edu.unsw.editingtool.global.GlobalConstant;

public class DBClaim extends DBManager {
		
	protected void setupDBMapping() {
		if (MappingTable.size() > 0)
			return;
		MappingTable.put("ClaimID", "claim_id");
		MappingTable.put("Username", "username");
		MappingTable.put("Publication", "pid");		
		MappingTable.put("Status", "cstatus");
		MappingTable.put("Reviewer", "reviewer");
		MappingTable.put("DateRequest", "date_request");
		MappingTable.put("DateApproved", "date_approved");
		MappingTable.put("Note", "note");
	}
	
	public DBClaim() {
		this.table = "claim";
		this.primaryKeys = new String[]{"ClaimID"};
		this.setupDBMapping();
	}
	
	// affiliation and pid is already solved
	//   -> affiliation can be found in login table. 
	public String addClaimRequest(String username, String pid) throws EditingToolException, ClassNotFoundException, SQLException 
	{
		String result = null;
		this.setTable(this.table, "");		
		Hashtable<String,String> claimInfo = new Hashtable<String,String>();
		claimInfo.put("Username",username);
		claimInfo.put("Publication",pid);
		Long currenttime = (new Date()).getTime();
		claimInfo.put("DateRequest",currenttime.toString());
		claimInfo.put("Status",GlobalConstant.claimRequest);
		this.setColumnValues(claimInfo);		
		this.initDB();
		
		this.insert(false, true);
		result = this.getGenerateKey();
		this.clean();
		return result;
	}
	
	// need to return different status to indicate weather there's no claim or it's not available.
	public int CheckClaim(String author, String pid) throws EditingToolException, ClassNotFoundException, SQLException {
		String fields[] = {"Status"};
		
		this.setTable(this.table, "");
		this.setFieldsCondition("Author", this.setEqual(author));
		this.setFieldsCondition("Publication", this.setEqual(pid));
		this.addField(fields);
		
		this.initDB();
		this.selectRecords();
		if (this.ResultSet == null) {
			this.clean();
			return 2;
		}
		if (!this.collectResults())
			return 2;
		for (int row = 0; row < Result.length / fields.length; row++) {
			for (int column = 0; column < fields.length; column++) {
				if (Result[row][column].equals(GlobalConstant.claimClaimed)) {
					this.clean();
					return 0;
				}
			}
		}
		this.clean();
		return 1;
	}
	
	public void setClaimStatus(String username, String pid, String status, String reviewer, String note) throws ClassNotFoundException, SQLException {
		this.setTable(this.table, "");
		this.setFieldsCondition("Username", this.setEqual(username));
		this.setFieldsCondition("Publication", this.setEqual(pid));
		Hashtable<String, String> record = new Hashtable<String, String>();
		record.put("Status", status);
		record.put("Reviewer", reviewer);		
		record.put("Note", note);
		if(status.compareTo(GlobalConstant.claimClaimed)==0)
		{
			Long currenttime = (new Date()).getTime();
			record.put("DateApproved", currenttime.toString());
		}
				
		this.initDB();
		this.setColumnValues(record);
		this.updateRecords();
		this.clean();
	}
	
	public String getStatus(String username, String pid) throws ClassNotFoundException, SQLException
	{
		String result = null;		
		
		int count = 0;
		String fields[] = {"Status"};
		this.setTable(this.table, "");
		this.setFieldsCondition("Username", this.setEqual(username));
		this.setFieldsCondition("Publication", this.setEqual(pid));		
		this.addField(fields);
				
		this.initDB();
		this.selectRecords();
		if (this.ResultSet == null) {
			System.out.println("[DBCLAIM] isClaimed NULL Resultset");
			this.clean();
			return null;
		}
		Long cstatus = new Long(0);
		while(this.ResultSet.next())
		{
			cstatus = (Long) ResultSet.getObject(1);
			count++;
		}
		if (count==1)
		{	
			System.out.println("[DBCLAIM] isClaimed Resultset Size is 1");									
			result = cstatus.toString();			
			this.clean();
			return result;
		}
		this.clean();		
		return result;			
	}
	
	public ArrayList<String> getResources(String username, String status) throws ClassNotFoundException, SQLException
	{
		ArrayList<String> result = new ArrayList<String>(); 
		int count = 0;
		String fields[] = {"Publication"};
		this.setTable(this.table, "");
		this.setFieldsCondition("Username", this.setEqual(username));
		this.setFieldsCondition("Status", this.setEqual(status));		
		this.addField(fields);
				
		this.initDB();
		this.selectRecords();
		if (this.ResultSet == null) {
			System.out.println("[DBCLAIM] getResources NULL Resultset");
			this.clean();
			return result;
		}
		while(this.ResultSet.next())
		{
			result.add(ResultSet.getObject(1).toString());
			count++;
		}
		this.clean();		
		return result;			
	}
	
	public Hashtable<String,ArrayList<String>> getResources(String status) throws ClassNotFoundException, SQLException
	{
		Hashtable<String,ArrayList<String>> result= new Hashtable<String,ArrayList<String>>();
		int count = 0;
		String fields[] = {"Username","Publication"};
		this.setTable(this.table, "");
		this.setFieldsCondition("Status", this.setEqual(status));		
		this.addField(fields);
				
		this.initDB();
		this.selectRecords();
		if (this.ResultSet == null) {
			System.out.println("[DBCLAIM] getResources NULL Resultset");
			this.clean();
			return result;
		}
		while(this.ResultSet.next())
		{
			String key = ResultSet.getObject(1).toString();
			String value = ResultSet.getObject(2).toString();
			if(!(result.containsKey(key)))
			{
				ArrayList<String> resultal = new ArrayList<String>(); 
				resultal.add(value);
				result.put(key,resultal);
			}
			else
			{
				ArrayList<String> resultal = result.get(key);
				resultal.add(value);
				result.put(key,resultal);
			}
			count++;
		}
		this.clean();		
		return result;			
	}
	
	public LinkedList<String[]> searchResources(String username, String pid) throws ClassNotFoundException, SQLException
	{
		LinkedList<String[]> result= new LinkedList<String[]>();
		int count = 0;
		String fields[] = {"Username","Publication","Status"};
		this.setTable(this.table, "");
		if(username!=null)
			this.setFieldsCondition("Username", this.setEqual(username));
		if(pid!=null)
			this.setFieldsCondition("Publication", this.setEqual(pid));
		this.addField(fields);
				
		this.initDB();
		this.selectRecords();
		
		if (this.ResultSet == null) {
			System.out.println("[DBCLAIM] getResources NULL Resultset");
			this.clean();
			return result;
		}
		while(this.ResultSet.next())
		{
			String key = ResultSet.getObject(1).toString();
			String value = ResultSet.getObject(2).toString();
			String status = ResultSet.getObject(3).toString();
			
			if(key!=null && value!=null && status!=null)
			{
				String[] resultarr = {key,value,status};
				result.add(resultarr);
			}				
			count++;
		}
		this.clean();		
		return result;			
	}
	
	public void deleteClaim(String username, String pid) throws ClassNotFoundException, SQLException
	{		
		String fields[] = {"Username","Publication"};		
		this.setTable(this.table, "");
		this.setFieldsCondition("Username", this.setEqual(username));
		this.setFieldsCondition("Publication", this.setEqual(pid));	
		this.addField(fields);
		this.initDB();
		this.deleteRecord();
		this.clean();
	}
}
